#include<iostream>
using namespace std;



//1.设计一个类不能被继承

/*C++98的方式：将父类的构造函数设置为私有，
 * 因为对于子类对象来说，创建子类对象的时候，需要先调用父类的构造函数来初始化父类的部分
 * 然后再调用子类的构造函数来初始化子类的部分，如果父类的构造私有，就会导致无法创建子类对象
 * 
 * 但这种方式，并不彻底！因为此时父类仍然可以被子类继承，只是子类无法实例化出对象
*/

/*
class NonExtendBase
{
private:
  NonExtendBase()
  {}
};

class Derive :public NonExtendBase
{
public:
    Derive() {}
};
*/

//C++11的方式：使用final修饰父类， 被final修饰的类称为最终类，无法被继承
// class NonExtendBase final
// {};

//设计一个类防拷贝
class NonCopy
{
public:
  NonCopy(){}
private:
  //C++11:用delete修饰被删除函数
  NonCopy(const NonCopy&) = delete;
  NonCopy& operator=(const NonCopy&) = delete;

  //C++98:私有&只声明不实现
};


//设计一个类只能在栈上创建对象
class StackOnly
{
public:
  static StackOnly GetObject()
  {
    return StackOnly(); //拷贝构造一个临时对象返回，所以拷贝构造不能封死
  }
private:
  StackOnly()
  {}
  void* operator new(size_t size) = delete;
  void operator delete(void* ptr) = delete;
};


//设计一个类只能在堆上创建对象
class HeapOnly
{
public:
  static HeapOnly* GetObject()
  {
    HeapOnly* ptr = new HeapOnly();
    return ptr;
  }
private:
  HeapOnly()
  {}
  HeapOnly(const HeapOnly&) =delete;
};

//限制：需要使用delete关键字，设计一个类只能在堆上创建对象
class HeapOnly_version2
{
public:
  static HeapOnly_version2& GetObject()
  {
    HeapOnly_version2* ptr = new HeapOnly_version2();
    return *ptr;
  }
  void Destroy()
  {
    delete[] _str;
    operator delete(this);
  }
  HeapOnly_version2()
  {
    _str = new char[10];
  }
private:
  ~HeapOnly_version2()
  {}

  char* _str;
};


